package com.nxy.cpfsfe.busi.unfyag;

import com.adtec.starring.datapool.EPOper;
import com.adtec.starring.exception.BaseException;
import com.adtec.starring.struct.dta.DtaInfo;
import com.adtec.starring.util.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.nxy.cpfsfe.PubBeanSerial;
import com.nxy.cpfsfe.enumtype.*;
import com.nxy.cpfsfe.mybatis.mapper.TbAMapper;
import com.nxy.cpfsfe.mybatis.mapper.TsPCmdMapper;
import com.nxy.cpfsfe.mybatis.pojo.TbA;
import com.nxy.cpfsfe.mybatis.pojo.TsPCmd;
import com.nxy.cpfsfe.service.CpfsService;
import com.nxy.cpfsfe.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by nxygyzd on 2019/12/12.
 *
 *  CPFS.104.001.01-积分支付异步服务
 */
public class PtPASrvBean implements CpfsService {

    private final static Logger LOGGER = LoggerFactory.getLogger(PtPASrvBean.class);

    private SqlSession sqlSession = (SqlSession) SpringUtil.getBean("mybatisSqlSession");

    /**
     * 服务入口
     */
    @Override
    public void doService() {

        Map<String,String> bizMap = null;

        try{
            String tpId = DtaInfo.getInstance().getTpId();
            String nginxUrl = (String) EPOper.get(tpId, "ReqBean[0].head[0].iPAddr");
            String bizMsg = (String) EPOper.get(tpId, "ReqBean[0].body[0].BizMsg");
            if(StringUtils.isBlank(nginxUrl)){
                throw new BaseException(RespCd.NCPO0110,"报文头缺少iPAddr属性");
            }
            if(bizMsg == null){
                throw new BaseException(RespCd.NCPO0110,"报文体缺少BizMsg属性");
            }
            LOGGER.info("接收到[{}]-[{}]：[{}]", MsgCdOrTpEnum.MSGTD_104.getCode(),MsgCdOrTpEnum.MSGTD_104.getName(),bizMsg);

            try{
                bizMap = XmlUtil.xml2Map(bizMsg);
                bizMap.put("NginxUrl",nginxUrl);
            }catch(Exception e){
                throw new BaseException(RespCd.NCPO0101,e,"报文体BizMsg属性值解析失败");
            }

            TsPCmd tsPCmd = insertTsPCmd(bizMap);
            TbA tbA = insertTbA(bizMap,tsPCmd);
            String resp10831 = snd10830(bizMap,tbA);
            handle10831(bizMap,resp10831,tsPCmd,tbA);
        }catch (BaseException e){
            String errMsg = String.format("[%s]报文处理失败，业务交易流水号TrxId=[%s]，[%s]",MsgCdOrTpEnum.MSGTD_104.getCode(),bizMap != null ? bizMap.get("/root/MsgHeader/TrxId") : "",e.getErrorDesc());
            LOGGER.error(errMsg,e);
            sndResp(bizMap,e,StatEnum.BIZSTA_FAIL.getCode(),StatEnum.BIZSTA_FAIL.getName(),false,false);
        } catch (Throwable e){
            String errMsg = String.format("[%s]报文处理失败，业务交易流水号TrxId=[%s]，[%s]",MsgCdOrTpEnum.MSGTD_104.getCode(),bizMap != null ? bizMap.get("/root/MsgHeader/TrxId") : "",e.getMessage());
            BaseException be = new BaseException(RespCd.NCPS7001,e,errMsg);
            LOGGER.error(be.getErrorDesc(),be);
            sndResp(bizMap,be,StatEnum.BIZSTA_FAIL.getCode(),StatEnum.BIZSTA_FAIL.getName(),false,false);
        }

    }

    /**
     *  入支付流水表
     */
    private TsPCmd insertTsPCmd(Map<String,String> bizMap){

        try{
            TsPCmdMapper tsPCmdMapper = sqlSession.getMapper(TsPCmdMapper.class);

            TsPCmd tsPCmdIC = new TsPCmd();
            tsPCmdIC.setCpfsD(DateUtil.str2Date(bizMap.get("/root/MsgBody/TrxInf/TrxDt"), "yyyyMMdd"));
            tsPCmdIC.setCpfsSeqNo(PubBeanSerial.getInstance().getSeqNoAndIncrea(TcSequenceEnum.CPFSSEQ.getCode()));
            tsPCmdIC.setBizSysD(DateUtil.str2Date(bizMap.get("/root/MsgHeader/SndDt"), "yyyy-MM-dd HH:mm:ss"));
            tsPCmdIC.setMsgTp(MsgCdOrTpEnum.MSGTD_104.getCode());
            tsPCmdIC.setComId(StringUtil.trimObject(bizMap.get("/root/MsgHeader/MsgTp")));
            tsPCmdIC.setComMsgId(StringUtil.trimObject(bizMap.get("/root/MsgHeader/CorrId")));
            tsPCmdIC.setBizSysId(StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndSysId")));
            tsPCmdIC.setXSeqNo(StringUtil.trimObject(bizMap.get("/root/MsgHeader/TrxId")));
            tsPCmdIC.setBizSta(StatEnum.BIZSTA_ING.getCode());
            tsPCmdIC.setBizTyp(TsPCmdEnum.BizTyp_Integre.getCode());
            tsPCmdIC.setBizCls(StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/BizKind")));
            tsPCmdIC.setEndToEndId(StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/EndToEndId")));
            tsPCmdIC.setShardingId(StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndBankId")));
            tsPCmdIC.setAcqOrgId(StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndBankId")));
            tsPCmdIC.setSndBNo(StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndBankId")));
            tsPCmdIC.setRcvBNo(StringUtil.trimObject(bizMap.get("/root/MsgHeader/RcvBankId")));
            tsPCmdIC.setOrdAmt(new BigDecimal(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/InstalAmt"))));
            if(StringUtils.isNotBlank(bizMap.get("/root/MsgBody/TrxInf/TrxFeeAmt"))){
                tsPCmdIC.setFeAmt(new BigDecimal(bizMap.get("/root/MsgBody/TrxInf/TrxFeeAmt")));
                if(tsPCmdIC.getFeAmt().compareTo(new BigDecimal("0")) == 1){
                    tsPCmdIC.setFeFlg("1");
                }else{
                    tsPCmdIC.setFeFlg("0");
                }
            }else{
                tsPCmdIC.setFeFlg("0");
                tsPCmdIC.setFeAmt(new BigDecimal("0.00"));
            }
            tsPCmdIC.setCashRmFlg(StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/TrxCashTp")));
            tsPCmdIC.setCurTyp(StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/TrxCurTp")));
            tsPCmdIC.setpTms(Integer.parseInt(StatEnum.PAY_TIMES_ONE.getCode()));
            Map<String ,Object> addInfo = new HashMap<String,Object>();
            addInfo.put("ClbckUrl",StringUtil.trimObject(bizMap.get("/root/MsgHeader/ClbckUrl")));
            addInfo.put("TrxUstrd",StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/TrxUstrd")));
            addInfo.put("NginxUrl",StringUtil.trimObject(bizMap.get("NginxUrl")));
            tsPCmdIC.setAddInfo(new JSONObject(addInfo).toJSONString());
            Map<String ,Object> pInfo = new HashMap<String,Object>();
            pInfo.put("TrxPurPose",StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/TrxPurPose")));
            pInfo.put("ExchPercent",StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/ExchPercent")));
            tsPCmdIC.setpInfo(new JSONObject(pInfo).toJSONString());
            tsPCmdIC.setChkASta(StatEnum.CHKASTA_NOT_START.getCode());
            tsPCmdIC.setAdjAFlg("0");
            tsPCmdIC.setCreTm(new Timestamp(new Date().getTime()));
            tsPCmdIC.setUpdTm(new Timestamp(new Date().getTime()));

            int result = tsPCmdMapper.insertByPo(tsPCmdIC);
            if(result != 1){
                String errMsg = String.format("[%s]入支付流水表[ts_p_cmd]失败，MyCat返回影响行数[%s]",MsgCdOrTpEnum.MSGTD_104.getCode(),result);
                BaseException be = new BaseException(RespCd.NCPS5002,errMsg);
                throw be;
            }

            LOGGER.info("成功录入支付流水表[ts_p_cmd]，前置流水号cpfsSeqNo=[{}]，业务通讯流水号comMsgId=[{}]，业务交易流水号xSeqNo=[{}]",
                    tsPCmdIC.getCpfsSeqNo(),tsPCmdIC.getComMsgId(),tsPCmdIC.getXSeqNo());
            return tsPCmdIC;
        }catch (BaseException e){
            throw e;
        }catch (Exception e){
            String errMsg = String.format("[%s]入支付流水表[ts_p_cmd]失败，[%s]",MsgCdOrTpEnum.MSGTD_104.getCode(),e.getMessage());
            BaseException be = new BaseException(RespCd.NCPS5002,e,errMsg);
            throw be;
        }

    }

    /**
     *  入账务流水表
     */
    private TbA insertTbA(Map<String,String> bizMap, TsPCmd tsPCmd){

        try{
            TbAMapper tbAMapper = sqlSession.getMapper(TbAMapper.class);

            TbA tbAIC = new TbA();
            tbAIC.setCpfsSeqNo(tsPCmd.getCpfsSeqNo());
            tbAIC.setCpfsD(tsPCmd.getCpfsD());
            tbAIC.setpNo("1");
            tbAIC.setShardingId(tsPCmd.getShardingId());
            tbAIC.setAcqOrgId(tsPCmd.getAcqOrgId());
            tbAIC.setDrcrFlg(TAbEnum.DrcrFlag_C.getCode());
            tbAIC.setBizTyp(tsPCmd.getBizTyp());
            tbAIC.setBizCls(tsPCmd.getBizCls());
            tbAIC.setSndSysId(tsPCmd.getBizSysId());
            tbAIC.setSndOrgId(tsPCmd.getSndBNo());
            tbAIC.setRcvSysId(StringUtil.trimObject(bizMap.get("/root/MsgHeader/RcvSysId")));
            tbAIC.setRcvOrgId(tsPCmd.getRcvBNo());
            tbAIC.setxDirn(TAbEnum.XDirn_In.getCode());
            tbAIC.setpCId(SysEcodeEnum.PESB.getCode());
            tbAIC.setChlXCd(MsgCdOrTpEnum.CBS_10830.getCode());
            tbAIC.setChlSeqNo(StringUtil.trimObject(bizMap.get("/root/MsgBody/TrxInf/TrxId")));
            tbAIC.setEndToEndId(tsPCmd.getEndToEndId());
            tbAIC.setxAmt(tsPCmd.getOrdAmt());
            tbAIC.setFeAmt(tsPCmd.getFeAmt());
            tbAIC.setCurTyp(tsPCmd.getCurTyp());
            tbAIC.setPtQty(Integer.parseInt(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/TransBonus"))));
            tbAIC.setCnvRt(new BigDecimal(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/InstalAmt"))));
            tbAIC.setPyrBNo(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/PyerMmbId")));
            tbAIC.setPyrBrchNo(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/PyerBrnchId")));
            tbAIC.setPyrA(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/PyerAcctNo")));
            tbAIC.setPyrNm(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyerInf/PyerAcctNm")));
            tbAIC.setPyeBNo(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyeeInf/PyeeMmbId")));
            tbAIC.setPyeBrchNo(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyeeInf/PyeeBrnchId")));
            tbAIC.setPyeA(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyeeInf/PyeeAcctNo")));
            tbAIC.setPyeNm(StringUtil.trimObject(bizMap.get("/root/MsgBody/PyeeInf/PyeeAcctNm")));
            tbAIC.setBizSta(StatEnum.BIZSTA_ING.getCode());
            tbAIC.setComMsgId(PubBeanSerial.getInstance().getSeqNoAndIncrea(TcSequenceEnum.SEQ_NB.getCode()));
            tbAIC.setChkASta(StatEnum.CHKASTA_NOT_START.getCode());
            tbAIC.setCreTm(new Timestamp(new Date().getTime()));
            tbAIC.setUpdTm(new Timestamp(new Date().getTime()));

            int result = tbAMapper.insert(tbAIC);
            if(result != 1){
                String errMsg = String.format("[%s]转[%s]入账务流水表[tb_a]失败，MyCat返回影响行数[%s]",MsgCdOrTpEnum.MSGTD_104.getCode(),MsgCdOrTpEnum.CBS_10830.getCode(),result);
                BaseException be = new BaseException(RespCd.NCPS5002,errMsg);
                throw be;
            }

            LOGGER.info("成功录入账务流水表[tb_a]，前置流水号cpfsSeqNo=[{}]，通道通讯流水号comMsgId=[{}]，通道交易流水号chlSeqNo=[{}]",
                    tbAIC.getCpfsSeqNo(),tbAIC.getComMsgId(),tbAIC.getChlSeqNo());
            return tbAIC;
        }catch (BaseException e){
            throw e;
        }catch (Exception e){
            String errMsg = String.format("[%s]转[%s]入账务流水表[tb_a]失败，[%s]",MsgCdOrTpEnum.MSGTD_104.getCode(),MsgCdOrTpEnum.CBS_10830.getCode(),e.getMessage());
            BaseException be = new BaseException(RespCd.NCPS5002,e,errMsg);
            throw be;
        }

    }

    /**
     *  向PESB发送CBS0010830报文
     */
    private String snd10830(Map<String,String> bizMap,TbA tbA){

        String tpId = DtaInfo.getInstance().getTpId();
        EPOper.put(tpId, "ReqBean[0].head[0].servEcd", RpcOutputInfoEnum.OutPutSvr_CpfsFwdThrdPrtS.getCode());
        EPOper.put(tpId, "ReqBean[0].head[0].sndAppCd", tbA.getSndSysId());
        EPOper.put(tpId, "ReqBean[0].head[0].rcvAppCd",SysEcodeEnum.PESB.getCode());
        EPOper.put(tpId, "ReqBean[0].head[0].reqServCd", MsgCdOrTpEnum.CBS_10830.getCode());
        EPOper.put(tpId, "ReqBean[0].head[0].initrSeqno",System.currentTimeMillis() + "");
        EPOper.getCompSDO(tpId, "ReqBody").setValue("BizMsg",bulid10830(bizMap,tbA));
        String respMsg = RpcCommUtil.getInstance().rpcFeToGWRetMsg(tpId, RpcOutputInfoEnum.OutputName_Pub_Cpfsgw.getCode(),RpcOutputInfoEnum.OutPutSvr_CpfsFwdThrdPrtS.getCode());

        return respMsg;

    }

    /**
     *  构建CBS0010830报文
     */
    private String bulid10830(Map<String,String> bizMap,TbA tbA){

        bizMap.put("seqNb",tbA.getComMsgId());
        return XmlCBSBuildUtil.buildCBS10830Xml(bizMap);

    }

    /**
     *  处理CBS0010831响应报文
     */
    private void handle10831(Map<String,String> bizMap,String respMsg,TsPCmd origTsPCmd,TbA origTbA){

        Map<String,String> respMap = null;
        try{
            respMap = XmlUtil.xml2Map(respMsg);
        }catch (Throwable e){
            LOGGER.info("未收到[{}]通道对通道交易流水号chlSeqNo=[{}]的[{}]有效的回执，需要主动查询该流水状态",SysEcodeEnum.PESB.getCode(),origTbA.getChlSeqNo(),MsgCdOrTpEnum.CBS_10830.getCode());

            sndResp(bizMap,null,StatEnum.BIZSTA_ING.getCode(),StatEnum.BIZSTA_ING.getName(),true,false);
            queryOrigTx(bizMap,origTsPCmd,origTbA);
            return;
        }

        try{
            Map<String,String> updMap = new HashMap<String,String>();
            updMap.put("retCd",StringUtil.trimObject(respMap.get("/transaction/header/status/retCd")));
            updMap.put("respMsgTyp",StringUtil.trimObject(respMap.get("/transaction/header/msg/msgCd")));
            updMap.put("respMsgId",StringUtil.trimObject(respMap.get("/transaction/body/response/bonusSysSeqNb")));
            updMap.put("respSta",StringUtil.trimObject(respMap.get("/transaction/body/response/instalStat")));
            updMap.put("desc",StringUtil.trimObject(respMap.get("/transaction/header/status/desc")));
            updMap.put("transDesc",StringUtil.trimObject(respMap.get("/transaction/body/response/transDesc")));

            updateOrigTx(updMap,origTsPCmd,origTbA);

            bizMap.put("MsgId",origTbA.getChlSeqNo());
            bizMap.put("EndToEndId",origTsPCmd.getEndToEndId());
            bizMap.put("SttlmDt",DateUtil.date4Str(origTsPCmd.getCpfsD()));
            bizMap.put("TrxPurpose", StringUtil.trimObject(JSONObject.parseObject(origTsPCmd.getpInfo()).getString("TrxPurPose")));
            bizMap.put("TrxRemark",origTbA.getReserved1());
            bizMap.put("InstalAmt",origTbA.getxAmt().toPlainString());
            bizMap.put("TrxCtgy",origTsPCmd.getBizTyp());
            bizMap.put("TxNcsId",origTbA.getChlSeqNo());
            bizMap.put("TrxAmt",origTbA.getxAmt().toPlainString());
            bizMap.put("TrxSysId",origTbA.getpCId());
            bizMap.put("TrxChnlTp","07");
            if(StatEnum.BIZSTA_SUC.getCode().equals(origTsPCmd.getBizSta())){
                sndResp(bizMap,null,origTsPCmd.getBizSta(),StatEnum.BIZSTA_SUC.getName(),false,false);
            }else{
                sndResp(bizMap,null,origTsPCmd.getBizSta(),origTsPCmd.getErrDesc(),false,false);
            }
        }catch (Throwable e){
            String errMsg = String.format("处理通道交易流水号chlSeqNo=[%s]的[%s]回执时出现异常，无法向Nginx返回响应",origTbA.getChlSeqNo(),MsgCdOrTpEnum.CBS_10831.getCode());
            LOGGER.error(errMsg,e);
        }

    }

    /**
     *  更新原交易状态
     */
    private void updateOrigTx(Map<String,String> updMap,TsPCmd origTsPCmd,TbA origTbA){

        TsPCmdMapper tsPCmdMapper = sqlSession.getMapper(TsPCmdMapper.class);
        TbAMapper tbAMapper = sqlSession.getMapper(TbAMapper.class);

        Map<String,Object> tbAUC = new HashMap<String,Object>();
        Map<String,Object> tsPCmdUC = new HashMap<String,Object>();

        tbAUC.put("acqOrgId",origTbA.getAcqOrgId());
        tbAUC.put("comMsgId",origTbA.getComMsgId());
        tbAUC.put("respMsgTyp",updMap.get("respMsgTyp"));
        tbAUC.put("respMsgId",updMap.get("respMsgId"));
        tbAUC.put("respSta",updMap.get("respSta"));
        if(!updMap.get("retCd").startsWith("00")){
            tbAUC.put("bizSta",StatEnum.BIZSTA_FAIL.getCode());
            tbAUC.put("errCd",updMap.get("retCd"));
            tbAUC.put("errDesc",updMap.get("desc"));
        }else if("20".equals(updMap.get("respSta"))){
            tbAUC.put("bizSta",StatEnum.BIZSTA_SUC.getCode());
        }else{
            tbAUC.put("bizSta",StatEnum.BIZSTA_FAIL.getCode());
            tbAUC.put("errCd",updMap.get("retCd"));
            tbAUC.put("errDesc",updMap.get("transDesc"));
        }
        tbAUC.put("updTm",new Date());

        tsPCmdUC.put("acqOrgId",origTsPCmd.getAcqOrgId());
        tsPCmdUC.put("comMsgId",origTsPCmd.getComMsgId());
        tsPCmdUC.put("bizSta",tbAUC.get("bizSta"));
        tsPCmdUC.put("errCd",StringUtil.trimObject(tbAUC.get("errCd")));
        tsPCmdUC.put("errDesc",StringUtil.trimObject(tbAUC.get("errDesc")));
        tsPCmdUC.put("updTm",tbAUC.get("updTm"));

        tbAMapper.updateByMap(tbAUC);
        tsPCmdMapper.updateByMap(tsPCmdUC);
        LOGGER.info("根据[{}]回执已将原流水状态更新",updMap.get("respMsgTyp"));

        origTsPCmd.setBizSta((String)tsPCmdUC.get("bizSta"));
        origTsPCmd.setErrDesc((String)tsPCmdUC.get("errDesc"));

    }

    /**
     *  主动向PESB查询流水状态
     */
    private void queryOrigTx(Map<String,String> bizMap,TsPCmd origTsPCmd,TbA origTbA){

        try{
            String resp10861 = snd10860(bizMap,origTbA);
            handle10861(bizMap,resp10861,origTsPCmd,origTbA);
        }catch (BaseException e){
            String errMsg = String.format("查询并更新原交易[chlSeqNo={}]失败，[{}]",origTbA.getChlSeqNo(),e.getErrorDesc());
            LOGGER.error(errMsg,e);
        }catch (Throwable e){
            String errMsg = String.format("查询并更新原交易[chlSeqNo={}]失败，[{}]",origTbA.getChlSeqNo(),e.getMessage());
            LOGGER.error(errMsg,e);
        }

    }

    /**
     *  向PESB发送CBS0010860报文
     */
    private String snd10860(Map<String,String> bizMap,TbA origTbA){

        String tpId = DtaInfo.getInstance().getTpId();
        EPOper.put(tpId, "ReqBean[0].head[0].servEcd", RpcOutputInfoEnum.OutPutSvr_CpfsFwdThrdPrtS.getCode());
        EPOper.put(tpId, "ReqBean[0].head[0].sndAppCd", origTbA.getSndSysId());
        EPOper.put(tpId, "ReqBean[0].head[0].rcvAppCd",SysEcodeEnum.PESB.getCode());
        EPOper.put(tpId, "ReqBean[0].head[0].reqServCd", MsgCdOrTpEnum.CBS_10860.getCode());
        EPOper.put(tpId, "ReqBean[0].head[0].initrSeqno",System.currentTimeMillis() + "");
        EPOper.getCompSDO(tpId, "ReqBody").setValue("BizMsg",build10860(bizMap));
        String respMsg = RpcCommUtil.getInstance().rpcFeToGWRetMsg(tpId, RpcOutputInfoEnum.OutputName_Pub_Cpfsgw.getCode(),RpcOutputInfoEnum.OutPutSvr_CpfsFwdThrdPrtS.getCode());

        return respMsg;

    }

    /**
     *  构建CBS0010860报文
     */
    private String build10860(Map<String,String> bizMap){

        bizMap.remove("seqNb");
        return XmlCBSBuildUtil.buildCBS10860Xml(bizMap);

    }

    /**
     *  处理CBS0010861响应报文
     */
    private void handle10861(Map<String,String> bizMap,String respMsg,TsPCmd origTsPCmd,TbA origTbA){

        Map<String,String> respMap = XmlUtil.xml2Map(respMsg);

        String retCd = StringUtil.trimObject(respMap.get("/transaction/header/status/retCd"));
        String desc = StringUtil.trimObject(respMap.get("/transaction/header/status/desc"));
        String respSta = StringUtil.trimObject(respMap.get("/transaction/body/response/hostSeqStat"));
        if(!retCd.startsWith("00")){
            LOGGER.info("向[{}]查询原交易[chlSeqNo={}]失败，[{}]",SysEcodeEnum.PESB.getCode(),origTbA.getChlSeqNo(),desc);
            return;
        }else if("3".equals(respSta)){
            LOGGER.info("根据查询流水回执[{}]，流水[chlSeqNo={}]仍在处理中...",MsgCdOrTpEnum.CBS_10861.getCode(),origTbA.getChlSeqNo());
            return;
        }else if("1".equals(respSta)){
            respSta = "20";
        }

        Map<String,String> updMap = new HashMap<String,String>();
        updMap.put("retCd",retCd);
        updMap.put("respMsgTyp",StringUtil.trimObject(respMap.get("/transaction/header/msg/msgCd")));
        updMap.put("respMsgId",StringUtil.trimObject(respMap.get("/transaction/body/response/hostSeqNb")));
        updMap.put("respSta",respSta);
        updMap.put("desc",desc);
        updMap.put("transDesc",StringUtil.trimObject(respMap.get("/transaction/body/response/errRes")));

        updateOrigTx(updMap,origTsPCmd,origTbA);

        bizMap.put("MsgId",origTbA.getChlSeqNo());
        bizMap.put("EndToEndId",origTsPCmd.getEndToEndId());
        bizMap.put("SttlmDt",DateUtil.date4Str(origTsPCmd.getCpfsD()));
        bizMap.put("TrxPurpose", StringUtil.trimObject(JSONObject.parseObject(origTsPCmd.getpInfo()).getString("TrxPurPose")));
        bizMap.put("TrxRemark",origTbA.getReserved1());
        bizMap.put("InstalAmt",origTbA.getxAmt().toPlainString());
        bizMap.put("TrxCtgy",origTsPCmd.getBizTyp());
        bizMap.put("TxNcsId",origTbA.getChlSeqNo());
        bizMap.put("TrxAmt",origTbA.getxAmt().toPlainString());
        bizMap.put("TrxSysId",origTbA.getpCId());
        bizMap.put("TrxChnlTp","07");
        if(StatEnum.BIZSTA_SUC.getCode().equals(origTsPCmd.getBizSta())){
            sndResp(bizMap,null,origTsPCmd.getBizSta(),StatEnum.BIZSTA_SUC.getName(),false,true);
        }else{
            sndResp(bizMap,null,origTsPCmd.getBizSta(),origTsPCmd.getErrDesc(),false,true);
        }

    }

    /**
     *  发送Nginx响应报文
     */
    private void sndResp(Map<String,String> bizMap,BaseException e,String bizSta,String bizDesc,boolean only501,boolean only502){

        if(bizMap == null){
            return;
        }

        try{
            String resp501Msg = buildNginxResp(bizMap,e,MsgCdOrTpEnum.MSGTD_501.getCode(),bizSta,bizDesc);
            String resp502Msg = buildNginxResp(bizMap,e,MsgCdOrTpEnum.MSGTD_502.getCode(),bizSta,bizDesc);

            if(only501){
                HttpHeaders headers = new HttpHeaders();
                headers.add("reqServCd",StringUtil.trimObject(bizMap.get("/root/MsgHeader/MsgTp")));
                headers.add("initrSeqno",StringUtil.trimObject(bizMap.get("/root/MsgHeader/CorrId")));
                headers.add("sndAppCd",StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndSysId")));
                headers.add("servInitrBrch",StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndBankId")));
                HttpUtil.responseSend(resp501Msg,bizMap.get("NginxUrl"),headers);
                return;
            }

            if(only502){
                HttpUtil.responseSend(resp502Msg,StringUtil.trimObject(bizMap.get("/root/MsgHeader/ClbckUrl")),new HttpHeaders());
                return;
            }

            HttpUtil.responseSendJson(resp501Msg,resp502Msg,bizMap);
        }catch (BaseException e1){
            String errMsg = String.format("向业务系统[%s]返回[%s]的处理响应[CPFS.501或CPFS.502]失败，业务交易流水号TrxId=[%s]，[%s]",bizMap.get("/root/MsgHeader/SndSysId"),MsgCdOrTpEnum.MSGTD_104.getCode(),bizMap.get("/root/MsgHeader/TrxId"),e1.getErrorDesc());
            LOGGER.error(errMsg,e1);
        }catch (Throwable e1){
            String errMsg = String.format("向业务系统[%s]返回[%s]的处理响应[CPFS.501或CPFS.502]失败，业务交易流水号TrxId=[%s]，[%s]",bizMap.get("/root/MsgHeader/SndSysId"),MsgCdOrTpEnum.MSGTD_104.getCode(),bizMap.get("/root/MsgHeader/TrxId"),e1.getMessage());
            LOGGER.error(errMsg,e1);
        }

    }

    /**
     * 构建响应Nginx的报文
     */
    private String buildNginxResp(Map<String,String> bizMap,BaseException e,String msgTp,String bizSta,String bizDesc) throws Exception{

        Map<String,String> buildMap = new HashMap<String,String>();
        buildMap.put("RcvSysId", StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndSysId")));
        buildMap.put("SndBankId",StringUtil.trimObject(bizMap.get("/root/MsgHeader/RcvBankId")));
        buildMap.put("RcvBankId",StringUtil.trimObject(bizMap.get("/root/MsgHeader/SndBankId")));
        buildMap.put("CorrId",StringUtil.trimObject(bizMap.get("/root/MsgHeader/CorrId")));
        buildMap.put("TrxId",StringUtil.trimObject(bizMap.get("/root/MsgHeader/TrxId")));
        buildMap.put("OriTrxId",StringUtil.trimObject(bizMap.get("/root/MsgHeader/TrxId")));
        if(StatEnum.BIZSTA_FAIL.getCode().equals(bizSta) && null != e){
            buildMap.put("TrxStsCd",e.getErrorCode());
        }else{
            buildMap.put("TrxStsCd",RespCd.NCPI0000);
        }
        buildMap.put("BizStsCd", bizSta);
        buildMap.put("BizStsDesc",bizDesc);

        buildMap.put("MsgId",bizMap.get("MsgId"));
        buildMap.put("EndToEndId",bizMap.get("EndToEndId"));
        buildMap.put("SttlmDt",bizMap.get("SttlmDt"));
        buildMap.put("TrxPurpose",bizMap.get("TrxPurpose"));
        buildMap.put("TrxRemark",bizMap.get("TrxRemark"));
        buildMap.put("InstalAmt",bizMap.get("InstalAmt"));
        buildMap.put("TrxCtgy",bizMap.get("TrxCtgy"));
        buildMap.put("TxNcsId",bizMap.get("TxNcsId"));
        buildMap.put("TrxAmt",bizMap.get("TrxAmt"));
        buildMap.put("TrxSysId",bizMap.get("TrxSysId"));
        buildMap.put("TrxChnlTp",bizMap.get("TrxChnlTp"));

        if(MsgCdOrTpEnum.MSGTD_501.getCode().equals(msgTp)){
            return ResponseUtil.buildGeneral501Xml(buildMap);
        }else{
            return ResponseUtil.buildGeneral502Xml(buildMap);
        }

    }

}
